/**
 * @Author 天下无敌
 * @Date 
 * @AIDE AIDE+ 
 */
package com.ecs.core.gsystem.chunk;
import com.artemis.systems.IteratingSystem;
import com.artemis.annotations.All;
import com.ecs.core.utils.FastNoiseLite;
import static com.ecs.core.GameContext.CHUNK_SIZE;
import com.ecs.core.map.TerrainData;
import com.ecs.core.gsystem.AssetsSystem;
import com.ecs.core.map.TerrainManager;
import com.ecs.core.EntityBuilder;
import com.badlogic.gdx.math.MathUtils;
//import com.ecs.core.debug.Debug;
import com.badlogic.gdx.utils.IntArray;
import com.ecs.core.GameContext;
import com.ecs.core.components.map.ChunkCom;
import com.artemis.ComponentMapper;
import com.ecs.core.components.attribute.Transform;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.ecs.core.map.TreeData;

@All({ChunkCom.class})
public class ChunkGeneraterSystem extends IteratingSystem
{
	public static final String TAG = "ChunkGeneraterSystem";
	private AssetsSystem assetManager;
	private ComponentMapper<ChunkCom> chunkComs;
	private ComponentMapper<Transform> transforms;
	private IntArray pendingGenChunk = new IntArray();
	
	private FastNoiseLite heightNoise = new FastNoiseLite();
	private FastNoiseLite moistureNoise = new FastNoiseLite();
	private FastNoiseLite tempNoise = new FastNoiseLite();
	
	private TerrainManager terrainManager;

	@Override
	protected void initialize()
	{
		super.initialize();
		terrainManager = new TerrainManager(assetManager.getAsset());
		initNoiseGenerators(MathUtils.random(1,10000000));
	}
	
	
	@Override
	protected void process(int p)
	{
		ChunkCom chunk = chunkComs.get(p);
		if(!chunk.isGen && world.getEntity(p).isActive()&& !pendingGenChunk.contains(p)){
			pendingGenChunk.add(p);
		}
	}

	@Override
	protected void end()
	{
		super.end();
		if(!pendingGenChunk.isEmpty()){
			generatorChunk(pendingGenChunk.removeIndex(0));
		}
	}
	
	public void generatorChunk(int p){
		//Debug.log(TAG,String.format("Generate Block %d",p));
		ChunkCom chunk = chunkComs.get(p);
		Transform chunkpos = transforms.get(p);;
		for(int x = 0;x < CHUNK_SIZE;x++){
			for(int y = 0;y< CHUNK_SIZE;y++){

				int mapX = (int)(chunkpos.getPosX()) + x;
				int mapY = (int)(chunkpos.getPosY()) + y;

				TerrainData terrain = terrainManager.matchesEnvironment(
					getNormalized(heightNoise,mapX,mapY),
					getNormalized(moistureNoise,mapX,mapY),
					getNormalized(tempNoise,mapX,mapY)
				);

				int id = EntityBuilder.init(world)
					.Pos(mapX,mapY)
					.Scale(1,1)
					.Terrain(terrain.terrainId,terrain.isWater)
					.ChunkTag(p)
					.Sprite(terrain.region,GameContext.LAYERE_0)
					.getId();

				chunk.activeEntityids.add(id);
				
				if((Math.random() * 10 > 7)){
					TreeData treedata = terrainManager.getRandomTrre(terrain.terrainId);
					if(treedata != null){
						TextureRegion reg = treedata.grow;
						int tid = EntityBuilder.init(world)
							.Pos(mapX,mapY)
							.Scale(1,1)
							.ChunkTag(p)
							.Tree(treedata.treeId)
							.Sprite(reg,GameContext.LAYERE_3)
							.getId();

						chunk.activeEntityids.add(tid);
					}
				}
			}
		}
		chunk.isGen = true;
	}

	// 初始化所有噪音生成器
	public void initNoiseGenerators(long seed) {
		// 高度噪音配置 - 用于地形高度
		heightNoise.SetSeed((int) seed);
		heightNoise.SetNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
		heightNoise.SetFrequency(0.01f); // 较低频率产生更平缓的地形
		heightNoise.SetFractalType(FastNoiseLite.FractalType.FBm);
		heightNoise.SetFractalOctaves(5); // 更多细节
		heightNoise.SetFractalLacunarity(2.0f);
		heightNoise.SetFractalGain(0.5f);

		// 湿度噪音配置 - 用于湿度分布
		moistureNoise.SetSeed((int) (seed + 1)); // 使用不同种子
		moistureNoise.SetNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
		moistureNoise.SetFrequency(0.02f); // 较高频率产生更多变化
		moistureNoise.SetFractalType(FastNoiseLite.FractalType.FBm);
		moistureNoise.SetFractalOctaves(3);

		// 温度噪音配置 - 用于温度分布
		tempNoise.SetSeed((int) (seed + 2)); // 使用不同种子
		tempNoise.SetNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
		tempNoise.SetFrequency(0.015f);
		tempNoise.SetFractalType(FastNoiseLite.FractalType.FBm);
		tempNoise.SetFractalOctaves(4);

	}

	// 获取归一化的高度噪音值 (0-1范围)
	public float getNormalized(FastNoiseLite noise,int x, int y) {
		float noiseValue = noise.GetNoise(x, y);
		return (noiseValue + 1) / 2f; // 将[-1,1]映射到[0,1]
	}

	@Override
	protected void dispose()
	{
		super.dispose();
		terrainManager.dispose();
	}

	
}
